(function (fruit, util) {
    /**
     * @class fruit.Collection
     */
    fruit.define('fruit.Collection', {
        properties: {
            length: {
                getter: function () {
                    return this._data.length;
                },
                readonly: true
            }
        },
        methods: {
            init: function (array) {
                this._data = array || [];
            },
            /**
             * Get an item by index.
             * @param index
             * @returns {*}
             */
            getItem: function (index) {
                return this._data[index];
            },
            /**
             * Get the index of specified item.
             * @param item
             * @returns {number}
             */
            indexOf: function (item) {
                var index = -1;
                util.forEach(this._data, function (data, i) {
                    if (util.equals(data, item)) {
                        index = i;
                    }
                });
                return index;
            },
            /**
             * Find out the item matching the iterator.
             * @param iterator
             * @param context
             * @returns {*}
             */
            find: function (iterator, context) {
                return util.find(this._data, iterator, context);
            },
            /**
             * Check whether the collection contains specified item.
             * @param item
             * @returns {boolean}
             */
            contains: function (item) {
                return this.indexOf(item) >= 0;
            },
            /**
             * Add an item.
             * @param item
             * @returns {boolean}
             */
            add: function (item) {
                this._data.push(item);
                return true;
            },
            /**
             * Remove an item.
             * @param item
             * @returns {boolean}
             */
            remove: function (item) {
                var data = this._data;
                var index = this.indexOf(item);
                if (index >= 0) {
                    data.splice(index, 1);
                    return true;
                }
                else {
                    return false;
                }
            },
            /**
             * Clear all items.
             * @returns {boolean}
             */
            clear: function () {
                this._data = [];
                return true;
            },
            /**
             * Iterate over items.
             * @param callback
             * @param context
             */
            forEach: function (callback, context) {
                util.forEach(this._data, callback, context);
            },
            /**
             * Convert collection to array.
             * @returns {Array}
             */
            toArray: function () {
                return this._data.slice(0);
            }
        }
    });
})(fruit, fruit.util);